home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / apps / database / postgres / postgre4.z / postgre4 / src / contrib / pgperl / pg-libpq.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-27  |  21.8 KB  |  861 lines

  1. /*
  2.  * Interface to Postgres 2.0
  3.  *
  4.  * $Header: /private/postgres/src/contrib/pgperl/RCS/pg-libpq.c,v 1.2 1991/03/08 13:22:28 kemnitz Exp $
  5.  *
  6.  * Tue Aug 21 14:13:40 1990  Igor Metz <metz@iam.unibe.ch>
  7.  *
  8.  * $Id: pg-libpq.c,v 1.2 1991/03/08 13:22:28 kemnitz Exp $
  9.  * $Log: pg-libpq.c,v $
  10.  * Revision 1.2  1991/03/08  13:22:28  kemnitz
  11.  * added RCS header.
  12.  *
  13.  * Revision 1.1  90/10/24  20:31:09  cimarron
  14.  * Initial revision
  15.  * 
  16. Revision 1.1  90/08/23  15:18:20  metz
  17. Initial revision
  18.  
  19.  * 
  20.  */
  21.  
  22. #include "tmp/libpq.h"
  23.  
  24. #include "EXTERN.h"
  25. #include "pg-perl.h"
  26.  
  27. static enum uservars {
  28.   UV_PQhost,
  29.   UV_PQport,
  30.   UV_PQtty,
  31.   UV_PQoption,
  32.   UV_PQdatabase,
  33.   UV_PQportset,
  34.   UV_PQxactid,
  35.   UV_PQinitstr,
  36.   UV_PQtracep
  37. };
  38.  
  39. static enum usersubs {
  40.   US_addPortal,
  41.   US_addGroup,
  42.   US_addTypes,
  43.   US_addTuples,
  44.   US_addTuple,
  45.   US_addValues,
  46.   US_addPortalEntry,
  47.   US_freePortalEntry,
  48.   US_freePortal,
  49.   US_portal_setup,
  50.   US_portal_close,
  51.   US_InitVacuumDemon,
  52.   US_PQnportals,
  53.   US_PQpnames,
  54.   US_PQparray,
  55.   US_PQrulep,
  56.   US_PQntuples,
  57.   US_PQngroups,
  58.   US_PQntuplesGroup,
  59.   US_PQnfieldsGroup,
  60.   US_PQfnumberGroup,
  61.   US_PQfnameGroup,
  62.   US_PQnfields,
  63.   US_PQfnumber,
  64.   US_PQfname,
  65.   US_PQftype,
  66.   US_PQsametype,
  67.   US_PQgetgroup,
  68.   US_PQgetvalue,
  69.   US_PQdb,
  70.   US_PQsetdb,
  71.   US_PQreset,
  72.   US_PQfinish,
  73.   US_PQtrace,
  74.   US_PQuntrace,
  75.   US_pqdebug,
  76.   US_pqdebug2,
  77.   US_read_initstr,
  78.   US_process_portal,
  79.   US_read_remark,
  80.   US_PQfn,
  81.   US_PQexec 
  82. };
  83.  
  84. static
  85. unsigned int
  86. dbl2uint(d)
  87.      double d;
  88. {
  89.   unsigned int i = d;
  90.   return i;
  91. }
  92.  
  93. static
  94. double
  95. uint2dbl(i)
  96.      unsigned int i;
  97. {
  98.   double d = i;
  99.   return d;
  100. }
  101.  
  102.  
  103. static int usersub();
  104. static int userset();
  105. static int userval();
  106.  
  107. extern void
  108. init_postgres_stuff()
  109. {    
  110.   struct ufuncs uf;
  111.   char *filename = "libpq.c";
  112.  
  113.   uf.uf_set = userset;
  114.   uf.uf_val = userval;
  115.  
  116. #define MAGICVAR(name, ix) uf.uf_index = ix, magicname(name, &uf, sizeof uf)
  117.  
  118.   /* register PG variables */
  119.   MAGICVAR("PQhost",        UV_PQhost);
  120.   MAGICVAR("PQport",        UV_PQport);
  121.   MAGICVAR("PQtty",        UV_PQtty);
  122.   MAGICVAR("PQoption",        UV_PQoption);
  123.   MAGICVAR("PQdatabase",    UV_PQdatabase);
  124.   MAGICVAR("PQportset",        UV_PQportset);
  125.   MAGICVAR("PQxactid",        UV_PQxactid);
  126.   MAGICVAR("PQinitstr",        UV_PQinitstr);
  127.   MAGICVAR("PQtracep",        UV_PQtracep);
  128.  
  129.   /* register PG functions */
  130.   make_usub("InitVacuumDemon",    US_InitVacuumDemon ,    usersub, filename);
  131.   make_usub("PQdb",        US_PQdb,        usersub, filename);
  132.   make_usub("PQexec",        US_PQexec ,        usersub, filename);
  133.   make_usub("PQfinish",        US_PQfinish ,        usersub, filename);
  134.   make_usub("PQfn",        US_PQfn ,        usersub, filename);
  135.   make_usub("PQfname",        US_PQfname,        usersub, filename);
  136.   make_usub("PQfnameGroup",    US_PQfnameGroup,    usersub, filename);
  137.   make_usub("PQfnumber",    US_PQfnumber,        usersub, filename);
  138.   make_usub("PQfnumberGroup",    US_PQfnumberGroup,    usersub, filename);
  139.   make_usub("PQftype",        US_PQftype,        usersub, filename);
  140.   make_usub("PQgetgroup",    US_PQgetgroup,        usersub, filename);
  141.   make_usub("PQgetvalue",    US_PQgetvalue,        usersub, filename);
  142.   make_usub("PQnfields",    US_PQnfields,        usersub, filename);
  143.   make_usub("PQnfieldsGroup",    US_PQnfieldsGroup,    usersub, filename);
  144.   make_usub("PQngroups",    US_PQngroups,        usersub, filename);
  145.   make_usub("PQnportals",    US_PQnportals,        usersub, filename);
  146.   make_usub("PQntuples",    US_PQntuples,        usersub, filename);
  147.   make_usub("PQntuplesGroup",    US_PQntuplesGroup,    usersub, filename);
  148.   make_usub("PQparray",        US_PQparray,        usersub, filename);
  149.   make_usub("PQpnames",        US_PQpnames,        usersub, filename);
  150.   make_usub("PQreset",        US_PQreset ,        usersub, filename);
  151.   make_usub("PQrulep",        US_PQrulep,        usersub, filename);
  152.   make_usub("PQsametype",    US_PQsametype,        usersub, filename);
  153.   make_usub("PQsetdb",        US_PQsetdb ,        usersub, filename);
  154.   make_usub("PQtrace",        US_PQtrace ,        usersub, filename);
  155.   make_usub("PQuntrace",    US_PQuntrace ,        usersub, filename);
  156.   make_usub("addGroup",        US_addGroup,        usersub, filename);
  157.   make_usub("addPortal",    US_addPortal,        usersub, filename);
  158.   make_usub("addPortalEntry",    US_addPortalEntry,    usersub, filename);
  159.   make_usub("addTuple",        US_addTuple,        usersub, filename);
  160.   make_usub("addTuples",    US_addTuples,        usersub, filename);
  161.   make_usub("addTypes",        US_addTypes,        usersub, filename);
  162.   make_usub("addValues",    US_addValues,        usersub, filename);
  163.   make_usub("freePortal",    US_freePortal,        usersub, filename);
  164.   make_usub("freePortalEntry",    US_freePortalEntry,    usersub, filename);
  165.   make_usub("portal_close",    US_portal_close,    usersub, filename);
  166.   make_usub("portal_setup",    US_portal_setup,    usersub, filename);
  167.   make_usub("pqdebug",        US_pqdebug ,        usersub, filename);
  168.   make_usub("pqdebug2",        US_pqdebug2 ,        usersub, filename);
  169.   make_usub("process_portal",    US_process_portal ,    usersub, filename);
  170.   make_usub("read_initstr",    US_read_initstr ,    usersub, filename);
  171.   make_usub("read_remark",    US_read_remark ,    usersub, filename);
  172. }
  173.  
  174. static int
  175. usersub(ix, sp, items)
  176.      int ix;
  177.      register int sp;
  178.      register int items;
  179. {
  180.   STR **st = stack->ary_array + sp;
  181.   register int i;
  182.   register char *tmps;
  183.   register STR *Str;        /* used in str_get and str_gnum macros */
  184.  
  185.   switch (ix) {
  186. /* Allocate a new portal buffer. */
  187.     case US_addPortal:
  188.     if (items != 0)
  189.         fatal("Usage: &addPortal()");
  190.     else {
  191.         PortalBuffer* retval;
  192.  
  193.         retval = addPortal();
  194.         str_numset(st[0],  uint2dbl((unsigned int) retval));
  195.     }
  196.     return sp;
  197.  
  198. /* Add a new tuple group to the portal. */
  199.     case US_addGroup:
  200.     if (items != 1)
  201.         fatal("Usage: &addGroup($portal)");
  202.     else {
  203.         GroupBuffer* retval;
  204.         PortalBuffer*    portal = (PortalBuffer*) dbl2uint(str_gnum(st[1]));
  205.  
  206.         retval = addGroup(portal);
  207.         str_numset(st[0],  uint2dbl((unsigned int) retval));
  208.     }
  209.     return sp;
  210.  
  211. /* Allocate n type blocks. */
  212.     case US_addTypes:
  213.     if (items != 1)
  214.         fatal("Usage: &addTypes($n)");
  215.     else {
  216.         TypeBlock* retval;
  217.         int        n =     (int    ) dbl2uint(str_gnum(st[1]));
  218.  
  219.         retval = addTypes(n);
  220.         str_numset(st[0],  uint2dbl((unsigned int) retval));
  221.     }
  222.     return sp;
  223.  
  224. /* Allocate a tuple block. */
  225.     case US_addTuples:
  226.     if (items != 0)
  227.         fatal("Usage: &addTuples()");
  228.     else {
  229.         TupleBlock* retval;
  230.  
  231.         retval = addTuples();
  232.         str_numset(st[0],  uint2dbl((unsigned int) retval));
  233.     }
  234.     return sp;
  235.  
  236. /* Allocate a tuple of n fields (attributes). */
  237.     case US_addTuple:
  238.     if (items != 1)
  239.         fatal("Usage: &addTuple($n)");
  240.     else {
  241.         char** retval;
  242.         int        n =     (int    ) dbl2uint(str_gnum(st[1]));
  243.  
  244.         retval = addTuple(n);
  245.         str_numset(st[0],  uint2dbl((unsigned int) retval));
  246.     }
  247.     return sp;
  248.  
  249. /* Allocate n bytes for a value. */
  250.     case US_addValues:
  251.     if (items != 1)
  252.         fatal("Usage: &addValues($n)");
  253.     else {
  254.         char* retval;
  255.         int        n =     (int    ) dbl2uint(str_gnum(st[1]));
  256.  
  257.         retval = addValues(n);
  258.         str_set(st[0], retval);
  259.     }
  260.     return sp;
  261.  
  262. /* Allocate a portal entry. */
  263.     case US_addPortalEntry:
  264.     if (items != 0)
  265.         fatal("Usage: &addPortalEntry()");
  266.     else {
  267.         PortalEntry* retval;
  268.  
  269.         retval = addPortalEntry();
  270.         str_numset(st[0],  uint2dbl((unsigned int) retval));
  271.     }
  272.     return sp;
  273.  
  274. /* Free a portal entry in the portal table, the portal is freed separately. */
  275.     case US_freePortalEntry:
  276.     if (items != 1)
  277.         fatal("Usage: &freePortalEntry($i)");
  278.     else {
  279.         /* int retval = 1; */
  280.         int        i =     (int    ) dbl2uint(str_gnum(st[1]));
  281.  
  282.         (void)freePortalEntry(i);
  283.         str_numset(st[0], 1.0);
  284.     }
  285.     return sp;
  286.  
  287.     case US_freePortal:
  288.     if (items != 1)
  289.         fatal("Usage: &freePortal($portal)");
  290.     else {
  291.         /* int retval = 1; */
  292.         PortalBuffer*    portal = (PortalBuffer*) dbl2uint(str_gnum(st[1]));
  293.  
  294.         (void)freePortal(portal);
  295.         str_numset(st[0], 1.0);
  296.     }
  297.     return sp;
  298.  
  299. /* Set up a portal for dumping data. */
  300.     case US_portal_setup:
  301.     if (items != 1)
  302.         fatal("Usage: &portal_setup($pname)");
  303.     else {
  304.         PortalBuffer* retval;
  305.         char*    pname =        str_get(st[1]);
  306.  
  307.         retval = portal_setup(pname);
  308.         str_numset(st[0],  uint2dbl((unsigned int) retval));
  309.     }
  310.     return sp;
  311.  
  312. /* Close a portal, remove it from the portal table and free up the space. */
  313.     case US_portal_close:
  314.     if (items != 1)
  315.         fatal("Usage: &portal_close($pname)");
  316.     else {
  317.         /* int retval = 1; */
  318.         char*    pname =        str_get(st[1]);
  319.  
  320.         (void)portal_close(pname);
  321.         str_numset(st[0], 1.0);
  322.     }
  323.     return sp;
  324.  
  325. /* 
  326.  * Return the number of open portals. 
  327.  * If rule_p, only return asynchronized portals. 
  328.  */
  329.     case US_PQnportals:
  330.     if (items != 1)
  331.         fatal("Usage: &PQnportals($rule_p)");
  332.     else {
  333.         int retval;
  334.         int        rule_p = (int    ) dbl2uint(str_gnum(st[1]));
  335.  
  336.         retval = PQnportals(rule_p);
  337.         str_numset(st[0],  uint2dbl((unsigned int) retval));
  338.     }
  339.     return sp;
  340.  
  341. /* 
  342.  * Return all the portal names.
  343.  * If rule_p, only return asynchronized portals. 
  344.  */
  345.     case US_PQpnames:
  346.     if (items != 2)
  347.         fatal("Usage: &PQpnames($pnames, $rule_p)");
  348.     else {
  349.         /* int retval = 1; */
  350.         char**    pnames = (char**) dbl2uint(str_gnum(st[1]));
  351.         int        rule_p = (int    ) dbl2uint(str_gnum(st[2]));
  352.  
  353.         (void)PQpnames(pnames, rule_p);
  354.         str_numset(st[0], 1.0);
  355.     }
  356.     return sp;
  357.  
  358. /* Return the portal buffer given a portal name. */
  359.     case US_PQparray:
  360.     if (items != 1)
  361.         fatal("Usage: &PQparray($pname)");
  362.     else {
  363.         PortalBuffer* retval;
  364.         char*    pname =        str_get(st[1]);
  365.  
  366.         retval = PQparray(pname);
  367.         str_numset(st[0],  uint2dbl((unsigned int) retval));
  368.     }
  369.     return sp;
  370.  
  371. /* Return 1 if an asynchronized portal. */
  372.     case US_PQrulep:
  373.     if (items != 1)
  374.         fatal("Usage: &PQrulep($portal)");
  375.     else {
  376.         int retval;
  377.         PortalBuffer*    portal = (PortalBuffer*) dbl2uint(str_gnum(st[1]));
  378.  
  379.         retval = PQrulep(portal);
  380.         str_numset(st[0],  uint2dbl((unsigned int) retval));
  381.     }
  382.     return sp;
  383.  
  384. /* Return the number of tuples in a portal buffer. */
  385.     case US_PQntuples:
  386.     if (items != 1)
  387.         fatal("Usage: &PQntuples($portal)");
  388.     else {
  389.         int retval;
  390.         PortalBuffer*    portal = (PortalBuffer*) dbl2uint(str_gnum(st[1]));
  391.  
  392.         retval = PQntuples(portal);
  393.         str_numset(st[0],  uint2dbl((unsigned int) retval));
  394.     }
  395.     return sp;
  396.  
  397. /* Return the number of tuple groups in a portal buffer. */
  398.     case US_PQngroups:
  399.     if (items != 1)
  400.         fatal("Usage: &PQngroups($portal)");
  401.     else {
  402.         int retval;
  403.         PortalBuffer*    portal = (PortalBuffer*) dbl2uint(str_gnum(st[1]));
  404.  
  405.         retval = PQngroups(portal);
  406.         str_numset(st[0],  uint2dbl((unsigned int) retval));
  407.     }
  408.     return sp;
  409.  
  410. /* Return the number of tuples in a tuple group. */
  411.     case US_PQntuplesGroup:
  412.     if (items != 2)
  413.         fatal("Usage: &PQntuplesGroup($portal, $group_index)");
  414.     else {
  415.         int retval;
  416.         PortalBuffer*    portal = (PortalBuffer*) dbl2uint(str_gnum(st[1]));
  417.         int        group_index = (int    ) dbl2uint(str_gnum(st[2]));
  418.  
  419.         retval = PQntuplesGroup(portal, group_index);
  420.         str_numset(st[0],  uint2dbl((unsigned int) retval));
  421.     }
  422.     return sp;
  423.  
  424. /* Return the number of fields in a tuple group. */
  425.     case US_PQnfieldsGroup:
  426.     if (items != 2)
  427.         fatal("Usage: &PQnfieldsGroup($portal, $group_index)");
  428.     else {
  429.         int retval;
  430.         PortalBuffer*    portal = (PortalBuffer*) dbl2uint(str_gnum(st[1]));
  431.         int        group_index = (int    ) dbl2uint(str_gnum(st[2]));
  432.  
  433.         retval = PQnfieldsGroup(portal, group_index);
  434.         str_numset(st[0],  uint2dbl((unsigned int) retval));
  435.     }
  436.     return sp;
  437.  
  438. /* Return the field number (index) given the group index and the field name. */
  439.     case US_PQfnumberGroup:
  440.     if (items != 3)
  441.         fatal("Usage: &PQfnumberGroup($portal, $group_index, $field_name)");
  442.     else {
  443.         int retval;
  444.         PortalBuffer*    portal = (PortalBuffer*) dbl2uint(str_gnum(st[1]));
  445.         int        group_index = (int    ) dbl2uint(str_gnum(st[2]));
  446.         char*    field_name =    str_get(st[3]);
  447.  
  448.         retval = PQfnumberGroup(portal, group_index, field_name);
  449.         str_numset(st[0],  uint2dbl((unsigned int) retval));
  450.     }
  451.     return sp;
  452.  
  453. /* Return the field (attribute) name given the group index and field index. */
  454.     case US_PQfnameGroup:
  455.     if (items != 3)
  456.         fatal("Usage: &PQfnameGroup($portal, $group_index, $field_number)");
  457.     else {
  458.         char* retval;
  459.         PortalBuffer*    portal = (PortalBuffer*) dbl2uint(str_gnum(st[1]));
  460.         int        group_index = (int    ) dbl2uint(str_gnum(st[2]));
  461.         int        field_number = (int    ) dbl2uint(str_gnum(st[3]));
  462.  
  463.         retval = PQfnameGroup(portal, group_index, field_number);
  464.         str_set(st[0], retval);
  465.     }
  466.     return sp;
  467.  
  468. /* Return the number of fields in a tuple. */
  469.     case US_PQnfields:
  470.     if (items != 2)
  471.         fatal("Usage: &PQnfields($portal, $tuple_index)");
  472.     else {
  473.         int retval;
  474.         PortalBuffer*    portal = (PortalBuffer*) dbl2uint(str_gnum(st[1]));
  475.         int        tuple_index = (int    ) dbl2uint(str_gnum(st[2]));
  476.  
  477.         retval = PQnfields(portal, tuple_index);
  478.         str_numset(st[0],  uint2dbl((unsigned int) retval));
  479.     }
  480.     return sp;
  481.  
  482. /* Return the field index of a given field name within a tuple. */
  483.     case US_PQfnumber:
  484.     if (items != 3)
  485.         fatal("Usage: &PQfnumber($portal, $tuple_index, $field_name)");
  486.     else {
  487.         int retval;
  488.         PortalBuffer*    portal = (PortalBuffer*) dbl2uint(str_gnum(st[1]));
  489.         int        tuple_index = (int    ) dbl2uint(str_gnum(st[2]));
  490.         char*    field_name =    str_get(st[3]);
  491.  
  492.         retval = PQfnumber(portal, tuple_index, field_name);
  493.         str_numset(st[0],  uint2dbl((unsigned int) retval));
  494.     }
  495.     return sp;
  496.  
  497. /* Return the name of a field. */
  498.     case US_PQfname:
  499.     if (items != 3)
  500.         fatal("Usage: &PQfname($portal, $tuple_index, $field_number)");
  501.     else {
  502.         char* retval;
  503.         PortalBuffer*    portal = (PortalBuffer*) dbl2uint(str_gnum(st[1]));
  504.         int        tuple_index = (int    ) dbl2uint(str_gnum(st[2]));
  505.         int        field_number = (int    ) dbl2uint(str_gnum(st[3]));
  506.  
  507.         retval = PQfname(portal, tuple_index, field_number);
  508.         str_set(st[0], retval);
  509.     }
  510.     return sp;
  511.  
  512. /* Return the type of a field. */
  513.     case US_PQftype:
  514.     if (items != 3)
  515.         fatal("Usage: &PQftype($portal, $tuple_index, $field_number)");
  516.     else {
  517.         int retval;
  518.         PortalBuffer*    portal = (PortalBuffer*) dbl2uint(str_gnum(st[1]));
  519.         int        tuple_index = (int    ) dbl2uint(str_gnum(st[2]));
  520.         int        field_number = (int    ) dbl2uint(str_gnum(st[3]));
  521.  
  522.         retval = PQftype(portal, tuple_index, field_number);
  523.         str_numset(st[0],  uint2dbl((unsigned int) retval));
  524.     }
  525.     return sp;
  526.  
  527. /* Return 1 if the two tuples have the same type (in the same group). */
  528.     case US_PQsametype:
  529.     if (items != 3)
  530.         fatal("Usage: &PQsametype($portal, $tuple_index1, $tuple_index2)");
  531.     else {
  532.         int retval;
  533.         PortalBuffer*    portal = (PortalBuffer*) dbl2uint(str_gnum(st[1]));
  534.         int        tuple_index1 = (int    ) dbl2uint(str_gnum(st[2]));
  535.         int        tuple_index2 = (int    ) dbl2uint(str_gnum(st[3]));
  536.  
  537.         retval = PQsametype(portal, tuple_index1, tuple_index2);
  538.         str_numset(st[0],  uint2dbl((unsigned int) retval));
  539.     }
  540.     return sp;
  541.  
  542.     case US_PQgetgroup:
  543.     if (items != 2)
  544.         fatal("Usage: &PQgetgroup($portal, $tuple_index)");
  545.     else {
  546.         int retval;
  547.         PortalBuffer*    portal = (PortalBuffer*) dbl2uint(str_gnum(st[1]));
  548.         int        tuple_index = (int    ) dbl2uint(str_gnum(st[2]));
  549.  
  550.         retval = PQgetgroup(portal, tuple_index);
  551.         str_numset(st[0],  uint2dbl((unsigned int) retval));
  552.     }
  553.     return sp;
  554.  
  555. /* Return an attribute (field) value. */
  556.     case US_PQgetvalue:
  557.     if (items != 3)
  558.         fatal("Usage: &PQgetvalue($portal, $tuple_index, $field_number)");
  559.     else {
  560.         char* retval;
  561.         PortalBuffer*    portal = (PortalBuffer*) dbl2uint(str_gnum(st[1]));
  562.         int        tuple_index = (int    ) dbl2uint(str_gnum(st[2]));
  563.         int        field_number = (int    ) dbl2uint(str_gnum(st[3]));
  564.  
  565.         retval = PQgetvalue(portal, tuple_index, field_number);
  566.         str_set(st[0], retval);
  567.     }
  568.     return sp;
  569.  
  570. /* Return the current database being accessed. */
  571.     case US_PQdb:
  572.     if (items != 0)
  573.         fatal("Usage: &PQdb()");
  574.     else {
  575.         char* retval;
  576.  
  577.         retval = PQdb();
  578.         str_set(st[0], retval);
  579.     }
  580.     return sp;
  581.  
  582. /* Make the specified database the current database. */
  583.     case US_PQsetdb:
  584.     if (items != 1)
  585.         fatal("Usage: &PQsetdb($dbname)");
  586.     else {
  587.         /* int retval = 1; */
  588.         char*    dbname =    str_get(st[1]);
  589.  
  590.         (void)PQsetdb(dbname);
  591.         str_numset(st[0], 1.0);
  592.     }
  593.     return sp;
  594.  
  595. /* Reset the communication port with the backend. */
  596.     case US_PQreset:
  597.     if (items != 0)
  598.         fatal("Usage: &PQreset()");
  599.     else {
  600.         /* int retval = 1; */
  601.  
  602.         (void)PQreset();
  603.         str_numset(st[0], 1.0);
  604.     }
  605.     return sp;
  606.  
  607. /* Close communication ports with the backend. */
  608.     case US_PQfinish:
  609.     if (items != 0)
  610.         fatal("Usage: &PQfinish()");
  611.     else {
  612.         /* int retval = 1; */
  613.  
  614.         (void)PQfinish();
  615.         str_numset(st[0], 1.0);
  616.     }
  617.     return sp;
  618.  
  619. /* Trace. */
  620.     case US_PQtrace:
  621.     if (items != 0)
  622.         fatal("Usage: &PQtrace()");
  623.     else {
  624.         /* int retval = 1; */
  625.  
  626.         (void)PQtrace();
  627.         str_numset(st[0], 1.0);
  628.     }
  629.     return sp;
  630.  
  631.     case US_PQuntrace:
  632.     if (items != 0)
  633.         fatal("Usage: &PQuntrace()");
  634.     else {
  635.         /* int retval = 1; */
  636.  
  637.         (void)PQuntrace();
  638.         str_numset(st[0], 1.0);
  639.     }
  640.     return sp;
  641.  
  642.     case US_pqdebug:
  643.     if (items != 2)
  644.         fatal("Usage: &pqdebug($target, $msg)");
  645.     else {
  646.         /* int retval = 1; */
  647.         char*    target =    str_get(st[1]);
  648.         char*    msg =        str_get(st[2]);
  649.  
  650.         (void)pqdebug(target, msg);
  651.         str_numset(st[0], 1.0);
  652.     }
  653.     return sp;
  654.  
  655.     case US_pqdebug2:
  656.     if (items != 3)
  657.         fatal("Usage: &pqdebug2($target, $msg1, $msg2)");
  658.     else {
  659.         /* int retval = 1; */
  660.         char*    target =    str_get(st[1]);
  661.         char*    msg1 =        str_get(st[2]);
  662.         char*    msg2 =        str_get(st[3]);
  663.  
  664.         (void)pqdebug2(target, msg1, msg2);
  665.         str_numset(st[0], 1.0);
  666.     }
  667.     return sp;
  668.  
  669. /*
  670.  * Read in the initialization string to be passed to the POSTGRES backend.
  671.  * The initstr has the format of
  672.  *      USER,DATABASE,TTY,OPTION\n
  673.  * If the variables do not have values yet, read in the values from the
  674.  * environment variables.  If the environment variable does not have a
  675.  * value, use the default value.
  676.  */
  677.     case US_read_initstr:
  678.     if (items != 0)
  679.         fatal("Usage: &read_initstr()");
  680.     else {
  681.         /* int retval = 1; */
  682.  
  683.         (void)read_initstr();
  684.         str_numset(st[0], 1.0);
  685.     }
  686.     return sp;
  687.  
  688. /*
  689.  * Process protal queries.
  690.  * Return values are the same as PQexec().
  691.  */
  692.     case US_process_portal:
  693.     if (items != 1)
  694.         fatal("Usage: &process_portal($rule_p)");
  695.     else {
  696.         char* retval;
  697.         int        rule_p = (int    ) dbl2uint(str_gnum(st[1]));
  698.  
  699.         retval = process_portal(rule_p);
  700.         str_set(st[0], retval);
  701.     }
  702.     return sp;
  703.  
  704. /* Read and discard remarks. */
  705.     case US_read_remark:
  706.     if (items != 1)
  707.         fatal("Usage: &read_remark($id)");
  708.     else {
  709.         int retval;
  710.         char*    id =        str_get(st[1]);
  711.  
  712.         retval = read_remark(id);
  713.         str_numset(st[0],  uint2dbl((unsigned int) retval));
  714.     }
  715.     return sp;
  716.  
  717. /*
  718.  * Send a function call to the POSTGRES backend.
  719.  *
  720.  * fnid         : function id
  721.  * result_buf   : pointer to result buffer (&int if integer)
  722.  * result_len   : length of return value.
  723.  * result_is_int: If the result is an integer, this must be non-zero
  724.  * args         : pointer to a NULL terminated arg array.
  725.  *                      (length, if integer, and result-pointer)
  726.  * nargs        : # of arguments in args array.
  727.  */
  728.     case US_PQfn:
  729.     if (items != 6)
  730.         fatal("Usage: &PQfn($fnid, $result_buf, $result_len, $result_is_int, $args, $nargs)");
  731.     else {
  732.         char* retval;
  733.         int        fnid =     (int    ) dbl2uint(str_gnum(st[1]));
  734.         int *    result_buf = (int *) dbl2uint(str_gnum(st[2]));
  735.         int        result_len = (int    ) dbl2uint(str_gnum(st[3]));
  736.         int        result_is_int = (int    ) dbl2uint(str_gnum(st[4]));
  737.         PQArgBlock*    args =     (PQArgBlock*) dbl2uint(str_gnum(st[5]));
  738.         int        nargs =     (int    ) dbl2uint(str_gnum(st[6]));
  739.  
  740.         retval = PQfn(fnid, result_buf, result_len, result_is_int, args, nargs);
  741.         str_set(st[0], retval);
  742.     }
  743.     return sp;
  744.  
  745. /*
  746.  * Send a query to the POSTGRES backend.
  747.  * The return value is a string.
  748.  * If there is an error: return "E error-message".
  749.  * If tuples are fetched from the backend, return "P portal-name".
  750.  * If a query is executed successfully but no tuples fetched,
  751.  * return "C query-command".
  752.  */
  753.     case US_PQexec:
  754.     if (items != 1)
  755.         fatal("Usage: &PQexec($query)");
  756.     else {
  757.         char* retval;
  758.         char*    query =        str_get(st[1]);
  759.  
  760.         retval = PQexec(query);
  761.         str_set(st[0], retval);
  762.     }
  763.     return sp;
  764.  
  765.     case US_InitVacuumDemon:
  766.     if (items != 6)
  767.         fatal("Usage: &InitVacuumDemon($host, $database, $terminal, $option, $port, $vacuum)");
  768.     else {
  769.         /* int retval = 1; */
  770.         String    host =     (String) dbl2uint(str_gnum(st[1]));
  771.         String    database = (String) dbl2uint(str_gnum(st[2]));
  772.         String    terminal = (String) dbl2uint(str_gnum(st[3]));
  773.         String    option = (String) dbl2uint(str_gnum(st[4]));
  774.         String    port =     (String) dbl2uint(str_gnum(st[5]));
  775.         String    vacuum = (String) dbl2uint(str_gnum(st[6]));
  776.  
  777.         (void)InitVacuumDemon(host, database, terminal, option, port, vacuum);
  778.         str_numset(st[0], 1.0);
  779.     }
  780.     return sp;
  781.  
  782.   default:
  783.     fatal("Unimplemented user-defined subroutine");
  784.   }
  785.   return sp;
  786. }
  787.  
  788. static int
  789. userval(ix, str)
  790.      int ix;
  791.      STR *str;
  792. {
  793.   switch (ix) {
  794.   case UV_PQhost:
  795.     str_set(str, PQhost);
  796.     break;
  797.   case UV_PQport:
  798.     str_set(str, PQport);
  799.     break;
  800.   case UV_PQtty:
  801.     str_set(str, PQtty);
  802.     break;
  803.   case UV_PQoption:
  804.     str_set(str, PQoption);
  805.     break;
  806.   case UV_PQdatabase:
  807.     str_set(str, PQdatabase);
  808.     break;
  809.   case UV_PQportset:
  810.     str_numset(str, PQportset);
  811.     break;
  812.   case UV_PQxactid:
  813.     str_numset(str, PQxactid);
  814.     break;
  815.   case UV_PQinitstr:
  816.     str_set(str, PQinitstr);
  817.     break;
  818.   case UV_PQtracep:
  819.     str_numset(str, PQtracep);
  820.     break;
  821.   }
  822.   return 0;
  823. }
  824.  
  825. static int
  826. userset(ix, str)
  827.      int ix;
  828.      STR *str;
  829. {
  830.   switch (ix) {
  831.   case UV_PQhost:
  832.     strcpy(PQhost, str_get(str));        /* hope it fits */
  833.     break;
  834.   case UV_PQport:
  835.     strcpy(PQport, str_get(str));        /* hope it fits */
  836.     break;
  837.   case UV_PQtty:
  838.     strcpy(PQtty, str_get(str));        /* hope it fits */
  839.     break;
  840.   case UV_PQoption:
  841.     strcpy(PQoption, str_get(str));        /* hope it fits */
  842.     break;
  843.   case UV_PQdatabase:
  844.     strcpy(PQdatabase, str_get(str));        /* hope it fits */
  845.     break;
  846.   case UV_PQportset:
  847.     PQportset = dbl2uint(str_gnum(str));
  848.     break;
  849.   case UV_PQxactid:
  850.     PQxactid = dbl2uint(str_gnum(str));
  851.     break;
  852.   case UV_PQinitstr:
  853.     strcpy(PQinitstr, str_get(str));        /* hope it fits */
  854.     break;
  855.   case UV_PQtracep:
  856.     PQtracep = dbl2uint(str_gnum(str));
  857.     break;
  858.   }
  859.   return 0;
  860. }
  861.